1 Overview & Summary

Transparent, fully reproducible rebuild of the MRD–PET/CT agreement and prognosis analysis using paired 2×2 data. All inputs are harmonised to canonical cell counts (a = MRD−/PET+, b = MRD−/PET−, c = MRD+/PET−, d = MRD+/PET+) with percentages back-calculated to counts by proportional allocation and reconciled to the reported cohort size (n), where needed.

Analysis sets: (i) Primary (MRD and PET/CT assessed at the same time point); (ii) Strict (Δ ≤ 30 days between MRD and PET/CT); (iii) Sensitivity (including reconstructed rows and prespecified exclusions). Agreement metrics: Per study we report the pooled concordant proportion (b+d)/n, Cohen’s κ (standard error and 95% confidence interval), McNemar mid-p, and Gwet’s AC1 and prevalence- and bias-adjusted κ (PABAK). Study-level κ is pooled using random-effects (restricted maximum likelihood) with Knapp–Hartung adjustment. Directional discordance is defined as log-odds(MRD−/PET+ vs MRD+/PET−) with Haldane–Anscombe correction and synthesised by random-effects meta-analysis; 95% prediction intervals are reported when estimable.

Fréchet–Hoeffding κ bounds: Identification regions are derived per study and for pooled marginals. In this build, bounds are presented graphically (Supplementary Methods/figure), whereas the corresponding summary table may be omitted if inputs are insufficient for tabulation; bounds frequently cross zero, indicating weak identifiability of κ and supporting cautious interpretation and a complementary view of MRD and PET/CT.

Survival (progression-free survival, PFS): Dual-negative (MRD−/PET−) versus all other response categories. Hazard ratios (HR) are pooled using random-effects (restricted maximum likelihood) with Knapp–Hartung, yielding a pooled HR of 0.33 (95% CI 0.24–0.45) favouring dual-negative versus others. Small-study asymmetry tests are interpreted descriptively given the limited number of cohorts.

Primary pooled 2×2 matrix (same-time-point set): MRD−/PET− 32.1% (n=374), MRD−/PET+ 37.4% (n=435), MRD+/PET− 26.1% (n=304), MRD+/PET+ 4.4% (n=51); analyzable paired n=1,164. Pooled concordant proportion = 36.5% and pooled κ = −0.26 (95% CI −0.31 to −0.21).

Key outputs: Table 1 (study characteristics); Table 2 (concordance and directional discordance); Figure 1 (PRISMA diagram); Figure 2A (pooled κ forest plot); Figure 2B (directional discordance meta-analysis); Figure 3A (PFS meta-analysis); Figure 3B (funnel plot); Supplementary Figure SF1 (pooled 2×2 matrix); Supplementary Tables ST1–ST2 (Fréchet–Hoeffding bounds and risk-of-bias). Optional supplementary outputs (simulation and decision-curve analysis) are omitted when required inputs are unavailable.

*Figure S1 omitted: simulation unavailable.**Figure S2 omitted: DCA inputs unavailable.*
*Table S1 omitted: could not compute FH bounds.*

2 Study Selection

2.1 Figure 1. PRISMA Diagram

2.2 Table 1. Study Characteristics

2.3 Supplementary Table ST1. Complete Log-Screen

3 Concordance analysis

3.1 Table 2. Concordance: κ and McNemar

Legend: columns in Table 2 (click to expand)
  • Study — Study identifier.
  • n — Total paired MRD–PET assessments.
  • MRD-/PET+ (a) — Discordant count.
  • MRD-/PET- (b) — Concordant dual-negative count.
  • MRD+/PET- (c) — Discordant count.
  • MRD+/PET+ (d) — Concordant dual-positive count.
  • %agree / pct_agree — Observed agreement (%) = 100 × (b + d) / n.
  • Kappa — Cohen’s κ (unitless).
  • SE, lower, upper — Standard error and 95% CI for κ.
  • McNemar_p — McNemar test p-value (a vs c).
  • McNemar_midp / mid_p — Mid-p McNemar p-value (if available).
  • AC1, AC1_se, AC1_lcl/ucl (or AC1_lower/upper) — Gwet’s AC1 and SE/95% CI.
  • PABAK, PABAK_lcl/ucl (or PABAK_lower/upper) — PABAK and its 95% CI.

3.2 Fréchet–Hoeffding bounds

ST1 source: tab2 (in-memory); n=10; cols = Study, n, MRD-/PET+, MRD-/PET-, MRD+/PET-, MRD+/PET+, pct_agree, Kappa, McNemar_p, AC1, AC1_se, AC1_lcl, AC1_ucl, PABAK, PABAK_lcl, PABAK_ucl

.

Supplementary Methods S3 – κ identification intervals (Fréchet–Hoeffding bounds) with point estimate

Supplementary Methods S3 – κ identification intervals (Fréchet–Hoeffding bounds) with point estimate

3.3 Figure 2A. Weighted Forest Plot

agg_png 
      2 

3.4 Figure 2B (PRIMARY)

B. Directional discordance (PRIMARY) — Lancet style

B. Directional discordance (PRIMARY) — Lancet style

3.5 Figure 2B (STRICT, Δ≤30): Directional discordance meta-analysis

Figure 2B (STRICT; Δ ≤ 30) — Directional discordance

Figure 2B (STRICT; Δ ≤ 30) — Directional discordance

3.6 Supplementary Figure SF1. Concordance matrix (pooled)

Supplementary Figure SF1. Concordance matrices for PRIMARY and STRICT time-points. STRICT applies the Δ(MRD–PET) ≤ 30 days rule to treat assessments as paired.

Supplementary Figure SF1. Concordance matrices for PRIMARY and STRICT time-points. STRICT applies the Δ(MRD–PET) ≤ 30 days rule to treat assessments as paired.

3.7 Supplementary Figure SF2. Discordance Strict Analysis

 <em>Strict analysis:</em> pooled log-odds = -0.67 (-2.02 &ndash; 0.68); I&sup2; = 94%
 </div>

4 Survival & meta-analysis

4.1 PFS Dual-negative vs others

PFS dual-negative vs others — 5 studies detected
Study logHR SE HR HR_lo HR_hi
Alonso R, Cedena MT, Gomez-Grande A, Rios R, Moraleda JM, Cabanas V, Moreno MJ, Lopez-Jimenez J, Martin F, Sanz A, Valeri A, Jimenez A, Sanchez R, Lahuerta JJ, Martinez-Lopez J -1.509 0.237 0.221 0.139 0.352
Moreau, P et al, 2019; Kraeber et al 2025 -0.935 0.273 0.393 0.230 0.670
Zamagni E, Oliva S, Gay F, Capra A, Rota-Scalabrini D, D’Agostino M, Belotti A, Galli M, Racca M, Zambello R, Gamberi B, Albano D, Bertamini L, Versari A, Grasso M, Sgherza N, Priola C, Fioritoni F, Patriarca F, De Cicco G, Villanova T, Pascarella A, Zucchetta P, Tacchetti P, Fanti S, Mancuso K, Barbato S, Boccadoro M, Musto P, Cavo M, Nanni C -0.799 0.342 0.450 0.230 0.880
Mookerjee A, Gupta R, Kumar R, Sharma A, Pandey RM, Kumar L -1.151 0.234 0.316 0.200 0.500
Fonseca R, Arribas M, Wiedmeier-Nutor JE, et al. -0.564 0.485 0.569 0.220 1.470

4.2 Figure 3. Forest:dual-negativity

Figure 3. Dual-negative MRD−/PET-CT− versus all other states: pooled hazard ratio for progression-free survival

Figure 3. Dual-negative MRD−/PET-CT− versus all other states: pooled hazard ratio for progression-free survival

Hazard ratios compare dual‑negative (MRD−/PET−) versus all other states. HRs and 95% CIs were used as reported when available; otherwise standardized from text fields or reconstructed from the reported CI on the log scale (normal approximation). Values < 1 favor dual‑negative; > 1 favor others. Pooling uses random‑effects REML with Knapp–Hartung; a prediction interval is shown when k ≥ 2.

4.3 PFS pooled summary

PFS pooled summary (dual-negative vs all others)
Random-effects REML with Knapp–Hartung. Values < 1 favor dual-negative.
Model k HR (95% CI) Prediction interval (HR) τ² I² (%)
REML (Knapp–Hartung) 5 0.34 (0.22–0.51) 0.18–0.64 0.03 26.73
Small-study asymmetry tests have low power when k < 10; interpret cautiously.

4.4 Figure 3B. Funnel plot

stopifnot(exists("surv_df"), nrow(surv_df) >= 1)

if (!exists("res_hr") || !inherits(res_hr, "rma.uni")) {
  res_hr <- metafor::rma(yi = surv_df$logHR, vi = surv_df$vi, method = "REML", test = "knha")
}
mu <- as.numeric(res_hr$b)

egger_p <- NA_real_
if (nrow(surv_df) >= 3) {
  eg <- metafor::regtest(res_hr, model = "rma")
  egger_p <- eg$pval
}
egger_lab <- if (is.finite(egger_p)) sprintf("Egger p = %.3f", egger_p) else "Egger p = NA"
# --------------------------------------------


# Limits from data to include ALL studies
x_min <- min(surv_df$logHR, na.rm = TRUE) - 0.15
x_max <- max(surv_df$logHR, na.rm = TRUE) + 0.15
y_max <- max(surv_df$SE,    na.rm = TRUE) + 0.02
y_seq <- seq(0, y_max, length.out = 200)

cone_left  <- data.frame(x = mu - 1.96*y_seq, y = y_seq)
cone_right <- data.frame(x = mu + 1.96*y_seq, y = y_seq)

p_fun <- ggplot(surv_df, aes(x = logHR, y = SE)) +
  geom_line(data = cone_left,  aes(x, y), linetype = "dashed") +
  geom_line(data = cone_right, aes(x, y), linetype = "dashed") +
  geom_vline(xintercept = mu, linetype = "dashed") +
  geom_point(size = 2.5) +
  ggrepel::geom_label_repel(aes(label = StudyShort),
                            size = 3, label.size = 0.25,
                            label.r = grid::unit(0.08, "lines"),  # <- change unit() -> grid::unit()
                            min.segment.length = 0, seed = 1234) +
coord_cartesian(xlim = c(x_min, x_max), expand = FALSE) +
  labs(x = "log(HR)", y = "SE", title = "Funnel plot (log(HR) vs SE)") +
annotate("text", x = x_max, y = y_max, hjust = 1.1, vjust = -0.5, label = egger_lab, size = 3) +
  theme_minimal(base_size = 11) +
  theme(panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5))

out_png <- here::here("figs","Figure_3B_Funnel.png")
ggsave(out_png, p_fun, width = 7.8, height = 5.0, dpi = 300, bg = "white")

cap <- if (exists("legend_for")) legend_for("Figure_3B_Funnel.png") else
  "B. Funnel plot (log(HR) vs SE). Dashed cone = ~95% pseudo-CIs; vertical line = pooled effect; Egger’s p shown; for k<10 interpret with caution."
if (file.exists(out_png)) { if (exists("show_png")) show_png("figs", basename(out_png), caption = cap, width = "95%") else knitr::include_graphics(out_png) }
B. Funnel plot (log(HR) vs SE). Dashed cone = ~95% pseudo-CIs; vertical line = pooled effect. Egger’s test p shown; for k<10 interpret with caution.

B. Funnel plot (log(HR) vs SE). Dashed cone = ~95% pseudo-CIs; vertical line = pooled effect. Egger’s test p shown; for k<10 interpret with caution.

Funnel plot shows study log(HR) on the x-axis versus its SE on the y-axis (inverted; more precise studies appear higher). The dashed vertical line marks the pooled center μ = -1.093. Slanted lines depict ~95% pseudo–confidence limits under a fixed pooled effect. Egger intercept p = 0.119 (k<10: low power). Asymmetry screens for small-study effects; it does not prove publication bias and may reflect true between-study differences.

4.5 Supplementary Figure SF3

Supplementary Figure SF3B. Bias of “marginals-only” κ (independence assumption). Using pooled MRD and PET marginals, we enumerate all feasible 2×2 tables and compute the true κ. Assuming independence from marginals alone yields κ=0; therefore bias = κindependence − κtrue = −κtrue. The curve below zero shows systematic pull toward the null (κ=0): understates concordance when κ>0 and masks discordance when κ<0. Compute κ from the full joint 2×2 (or report identified-set bounds).

4.6 Supplementary Table ST2 (Leave-one-out, Egger table, Baujat)

ST2: Egger summary — PFS HR (dual−negative vs others)
model k center_log Egger_p
REML (Knapp–Hartung) 5.000 −1.093 0.119
Egger’s test has low power for k < 10; interpret with caution.
Leave-one-out (sorted by |Δ pooled|)
Study Center LOO_est LOO_se Delta LCL UCL HR_center HR HR_LCL HR_UCL
Alonso −1.093 −0.962 0.108 0.130 −1.175 −0.750 0.335 0.382 0.309 0.472
Zamagni −1.093 −1.147 0.171 0.055 −1.483 −0.812 0.335 0.318 0.227 0.444
Fonseca −1.093 −1.146 0.152 0.053 −1.444 −0.848 0.335 0.318 0.236 0.428
Mookerjee −1.093 −1.041 0.202 0.051 −1.437 −0.646 0.335 0.353 0.238 0.524
Moreau 2019 −1.093 −1.121 0.192 0.029 −1.497 −0.745 0.335 0.326 0.224 0.475
Baujat plot

Baujat plot

           x          y ids slab
1 1.99245249 1.44781779   1    1
2 0.23620252 0.02205887   2    2
3 0.58403678 0.10144991   3    3
4 0.04032006 0.06436193   4    4
5 1.05091602 0.12297498   5    5

4.7 Risk of Bias: import & quick previews

#QUIPS / QUADAS-2: setup, templates, and import

5 Traffic-light plots (QUIPS & QUADAS-2) + domain summaries

6 Concordance (QUADAS-2): annotate plots and do sensitivity

Sensitivity (exclude QUADAS-2 High): κ = 0.163 (0.103–0.224)

7 Risk of Bias

NULL [1] “figs/Supplementary_Figure_QUADAS2_Traffic.png” attr(,“class”) [1] “knit_image_paths” “knit_asis”
QUIPS overall unavailable or only one level → subgroup meta skipped.

8 Supplementary Tables ST3 - ST4

8.1 Table 3 - Subgroup outcomes (as reported)

Download MASTER (xlsx) ST3 (xlsx) ST4 (xlsx)

9 Conceptual diagram

Clinical pathway schematic mapping 2×2 states to suggested actions.

Clinical pathway schematic mapping 2×2 states to suggested actions.

10 Download bundle

Supplementary Figures (ZIP) (5.1 MB)   Supplementary Tables (ZIP) (55.9 KB)   Complete Supplementary Bundle (ZIP) (5.2 MB)

11 Summary

12 Session Info

sessionInfo()
R version 4.5.2 (2025-10-31)
Platform: x86_64-apple-darwin20
Running under: macOS Sequoia 15.4.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.5-x86_64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-x86_64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Zurich
tzcode source: internal

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] fs_1.6.6            patchwork_1.3.2     knitr_1.51          rlang_1.1.6         gt_1.2.0           
 [6] metasens_1.5-3      rsvg_2.7.0          DiagrammeRsvg_0.1   DiagrammeR_1.0.11   here_1.0.2         
[11] ggforce_0.5.0       RColorBrewer_1.1-3  htmltools_0.5.9     DT_0.34.0           zip_2.3.3          
[16] htmlwidgets_1.6.4   DescTools_0.99.60   writexl_1.5.4       glue_1.8.0          scales_1.4.0       
[21] ggrepel_0.9.6       png_0.1-8           cowplot_1.2.0       broom_1.0.11        janitor_2.2.1      
[26] irr_0.84.1          lpSolve_5.6.23      meta_8.2-1          metafor_4.8-0       numDeriv_2016.8-1.1
[31] metadat_1.4-0       Matrix_1.7-4        readxl_1.4.5        lubridate_1.9.4     forcats_1.0.1      
[36] stringr_1.6.0       dplyr_1.1.4         purrr_1.2.0         readr_2.1.6         tidyr_1.3.2        
[41] tibble_3.3.0        ggplot2_4.0.1       tidyverse_2.0.0    

loaded via a namespace (and not attached):
 [1] mathjaxr_2.0-0     rstudioapi_0.17.1  jsonlite_2.0.0     magrittr_2.0.4     magick_2.9.0       farver_2.1.2      
 [7] nloptr_2.2.1       rmarkdown_2.30     ragg_1.5.0         vctrs_0.6.5        minqa_1.2.8        CompQuadForm_1.4.4
[13] curl_7.0.0         haven_2.5.5        cellranger_1.1.0   sass_0.4.10        bslib_0.9.0        rootSolve_1.8.2.4 
[19] cachem_1.1.0       commonmark_2.0.0   lifecycle_1.0.4    pkgconfig_2.0.3    R6_2.6.1           fastmap_1.2.0     
[25] rbibutils_2.4      snakecase_0.11.1   digest_0.6.39      Exact_3.3          rprojroot_2.1.1    textshaping_1.0.4 
[31] crosstalk_1.2.2    labeling_0.4.3     timechange_0.3.0   httr_1.4.7         polyclip_1.10-7    compiler_4.5.2    
[37] proxy_0.4-28       bit64_4.6.0-1      withr_3.0.2        S7_0.2.1           backports_1.5.0    MASS_7.3-65       
[43] gtools_3.9.5       gld_2.6.8          tools_4.5.2        otel_0.2.0         nlme_3.1-168       generics_0.1.4    
[49] gtable_0.3.6       tzdb_0.5.0         class_7.3-23       data.table_1.18.0  lmom_3.2           hms_1.1.4         
[55] xml2_1.5.1         pillar_1.11.1      markdown_2.0       vroom_1.6.7        splines_4.5.2      tweenr_2.0.3      
[61] lattice_0.22-7     bit_4.6.0          tidyselect_1.2.1   juicyjuice_0.1.0   reformulas_0.4.3   V8_8.0.1          
[67] litedown_0.9       xfun_0.55          expm_1.0-0         visNetwork_2.1.4   stringi_1.8.7      yaml_2.3.12       
[73] boot_1.3-32        evaluate_1.0.5     robvis_0.3.0       cli_3.6.5          systemfonts_1.3.1  Rdpack_2.6.4      
[79] jquerylib_0.1.4    dichromat_2.0-0.1  Rcpp_1.1.0         parallel_4.5.2     lme4_1.1-38        mvtnorm_1.3-3     
[85] e1071_1.7-17       crayon_1.5.3